package parte1;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

/**
 * Classe de um usuario
 * 
 * @author Samuel Wesley, Wellington Araújo, Gervásio Costa
 * 
 **/
public class Usuario implements Serializable {
	private static final long serialVersionUID = 1L;
	private String nome, descricao, email;
	private ArrayList<Evento> eventos = new ArrayList<Evento>();
	private ArrayList<Contato> contatos = new ArrayList<Contato>();

	/**
	 * Construtor de usuario
	 * 
	 * @param nome
	 *            String com o nome do usuario
	 * @param descricao
	 *            String com a descricao do usuario
	 * @param email
	 *            String com o email do usuario
	 * 
	 **/
	public Usuario(String nome, String descricao, String email) {
		this.nome = nome;
		this.descricao = descricao;
		this.email = email;
	}

	/**
	 * Metódo que classifica eventos em eventos passados
	 * 
	 * @return List com eventos passados
	 */

	public List<Evento> getEventosPassados() {
		Calendar tempoAtual = new GregorianCalendar();
		List<Evento> eventosPassados = new ArrayList<Evento>();
		for (Evento evento : eventos) {
			if (evento.getDataInicial().before(tempoAtual))
				eventosPassados.add(evento);
		}
		return eventosPassados;
	}

	/**
	 * Metódo que retorna uma lista de eventos
	 * 
	 * @return List com todos os eventos
	 */
	public List<Evento> getEventos() {
		return eventos;
	}

	/**
	 * Metódo que classifica eventos em eventos futuros
	 * 
	 * @return List com eventos futuros
	 */
	public List<Evento> getEventosFuturos() {
		Calendar tempoAtual = new GregorianCalendar();
		List<Evento> eventosFuturos = new ArrayList<Evento>();
		for (Evento evento : eventos) {
			if (evento.getDataInicial().after(tempoAtual))
				eventosFuturos.add(evento);
		}
		return eventosFuturos;
	}

	/**
	 * Metódo que retorna uma lista de contatos
	 * 
	 * @return List de contatos
	 */
	public List<Contato> getContatos() {
		return contatos;
	}

	/**
	 * Metódo que adiciona um contato numa lista de contatos
	 * 
	 * @param c
	 *            Parâmetro que recebe um objeto do tipo Contato
	 */
	public void addContato(Contato c) {
		if (!contatos.contains(c))
			contatos.add(c);
	}

	/**
	 * Metódo que adiciona um evento numa lista de eventos
	 * 
	 * @param e
	 *            Parâmetro que recebe um objeto do tipo Evento
	 */
	public void addEvento(Evento e) {
		if (!eventos.contains(e))
			eventos.add(e);
	}

	/**
	 * Metódo que retorna o nome do usuario
	 * 
	 * @return O nome do usuario
	 */
	public String getNome() {
		return nome;
	}

	/**
	 * Metódo que modifica o nome do usuario
	 * 
	 * @param nome
	 *            String com o novo nome do usuario
	 */
	public void setNome(String nome) {
		this.nome = nome;
	}

	/**
	 * Metódo que retorna a descricao do usuario
	 * 
	 * @return descricao do usuario
	 */
	public String getDescricao() {
		return descricao;
	}

	/**
	 * Metódo que modifica a descricao do usuario
	 * 
	 * @param descricao
	 *            String com a nova descricao do usuario
	 */
	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	/**
	 * Metodo que retorna o email do usuario
	 * 
	 * @return String com o email do usuario
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * Metodo que modifica o email do usuario
	 * 
	 * @param email
	 *            String com o novo email do usuario
	 */
	public void setEmail(String email) {
		this.email = email;
	}

	/**
	 * Método que remove um Contato da lista de contatos do Usuário
	 * 
	 * @param contato
	 *            Contato que se deseja remover dos contatos do Usuário
	 * @return true se o contato existir na lista e tiver sido removido. Caso
	 *         contrário, retorna false.
	 */
	public boolean removeContato(Contato contato) {
		for (Evento evento : contato.getEventos()) {
			evento.removeContato(contato);
		}
		return contatos.remove(contato);
	}

	/**
	 * Método que remove um Evento da lista dos eventos do Usuário
	 * 
	 * @param evento
	 *            Evento que se deseja remover dos eventos do Usuário
	 * @return true se o contato existir na lista e tiver sido removido. Caso
	 *         contrário, retorna false.
	 */
	public boolean removeEvento(Evento evento) {
		for (Contato contato : evento.getContatosNoEvento()) {
			contato.removeEvento(evento);
		}
		return eventos.remove(evento);
	}

	/**
	 * Método que retorna uma String com as informações do Usuário
	 * 
	 * @return String com as informações do Usuário (nome, e-mail e descrição)
	 */
	@Override
	public String toString() {
		return nome + "\n" + email + "\n" + descricao;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((email == null) ? 0 : email.hashCode());
		result = prime * result + ((nome == null) ? 0 : nome.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Usuario other = (Usuario) obj;
		if (email == null) {
			if (other.email != null)
				return false;
		} else if (!email.equals(other.email))
			return false;
		if (nome == null) {
			if (other.nome != null)
				return false;
		} else if (!nome.equals(other.nome))
			return false;
		return true;
	}

}
